﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.IO;
using System.Xml;
using TomanuExtensions;
using TomanuExtensions.Utils;

namespace AmiEmuLib.Render.Filter.ShaderFilter
{
    [DebuggerDisplay("Name = {Name}, FileName = {FileName}")]
    public class Shader : XmlBase
    {
        /// <summary>
        /// Shader name.
        /// </summary>
        public string Name { get; private set; }

        /// <summary>
        /// Resource name.
        /// </summary>
        public string FileName { get; private set; }

        /// <summary>
        /// This is include file for another shaders. Should not be showed on filter list in GUI.
        /// </summary>
        public bool Include { get; private set; }

        /// <summary>
        /// Indicate that shader is for internal procesing. Should not be showed on filter list in GUI.
        /// </summary>
        public bool Internal { get; private set; }

        /// <summary>
        /// Constructor.
        /// </summary>
        internal Shader(XmlReader a_reader)
            : base(a_reader)
        {
        }

        protected override void ReadXml(XmlReader a_reader)
        {
            a_reader.ReadStartElement(GetType().Name);

            Name = a_reader.ReadElementString("Name");
            FileName = a_reader.ReadElementString("FileName");

            if (a_reader.IsStartElement("Include"))
                Include = a_reader.ReadElementContentAsBoolean("Include");
            if (a_reader.IsStartElement("Internal"))
                Internal = a_reader.ReadElementContentAsBoolean("Internal");

            a_reader.ReadEndElement();
        }

        public override void WriteXml(XmlWriter a_writer)
        {
            a_writer.WriteStartElement(GetType().Name);

            a_writer.WriteElement("Name", Name);
            a_writer.WriteElement("FileName", FileName);

            if (Include)
                a_writer.WriteElement("Include", Include);
            if (Internal)
                 a_writer.WriteElement("Internal", Internal);

            a_writer.WriteEndElement();
        }

        /// <summary>
        /// Return shader code.
        /// </summary>
        /// <returns></returns>
        public string GetCode()
        {
            using (var stream = GetStream())
            {
                if (stream == null)
                    return null;

                StreamReader reader = new StreamReader(stream);
                return reader.ReadToEnd();
            }
        }

        /// <summary>
        /// Return stream if shader code.
        /// </summary>
        /// <returns></returns>
        public Stream GetStream()
        {
            if (FileName == "")
                return null;

            return StreamExtensions.FromResource(typeof(Shader), FileName, "FX");
        }
    }
}
